﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
//MicroDesigner
using Jc.MicroDesigner.Events;
using Jc.MicroDesigner.Objects;

namespace Jc.MicroDesigner.Drawings
{
    /// <summary>
    /// Класс, отвечающий за отрисовку элементов
    /// </summary>
    public class ElementImage
    {
        #region Private

        /// <summary>
        /// Отступ сверху
        /// </summary>
        protected int _Top = 0;

        /// <summary>
        /// Отступ слева
        /// </summary>
        protected int _Left = 0;

        /// <summary>
        /// Высота
        /// </summary>
        protected int _Height = 0;

        /// <summary>
        /// Ширина
        /// </summary>
        protected int _Width = 0;

        /// <summary>
        /// Шаблон
        /// </summary>
        protected Image _TemplateImage = null;

        /// <summary>
        /// Результат
        /// </summary>
        protected Image _ResultImage = null;

        /// <summary>
        /// Файл изображения
        /// </summary>
        protected string _ImgFile = String.Empty;

        /// <summary>
        /// Событие отрисовки
        /// </summary>
        protected onPaintElement _onPaint = null;
        
        /// <summary>
        /// Событие обновления
        /// </summary>
        protected onRefreshTemplate _onRefresh = null;

        /// <summary>
        /// Элемент
        /// </summary>
        protected BaseElement _Parent = null;

        #endregion

        #region Properties

        /// <summary>
        /// Отступ слева
        /// </summary>
        public int Left
        {
            get
            {
                return _Left;
            }
            set
            {
                _Left = value;
            }
        }

        /// <summary>
        /// Отступ сверху
        /// </summary>
        public int Top
        {
            get
            {
                return _Top;
            }
            set
            {
                _Top = value;
            }
        }

        /// <summary>
        /// Ширина рабочей области
        /// </summary>
        public int Width
        {
            get
            {
                return _Width;
            }
            set
            {
                _Width = value;
            }
        }

        /// <summary>
        /// Высота рабочей области
        /// </summary>
        public int Height
        {
            get
            {
                return _Height;
            }
            set
            {
                _Height = value;
            }
        }

        /// <summary>
        /// Путь к файлу с изображением
        /// </summary>
        public string ImageFile
        {
            get
            {
                return _ImgFile;
            }
            set
            {
                if (File.Exists(value))
                {
                    _ImgFile = value;
                    _TemplateImage = Image.FromFile(value);
                    _Width = _TemplateImage.Width;
                    _Height = _TemplateImage.Height;
                }
                else
                    _ImgFile = String.Empty;
            }
        }

        /// <summary>
        /// Отрисовываемый элемент
        /// </summary>
        public BaseElement Parent
        {
            get
            {
                return _Parent;
            }
        }

        /// <summary>
        /// Событие отрисовки элемента
        /// </summary>
        public event onPaintElement onPaint
        {
            add
            {
                _onPaint += value;
            }
            remove
            {
                _onPaint -= value;
            }
        }

        /// <summary>
        /// Событие обновления элемента
        /// </summary>
        public event onRefreshTemplate onRefresh
        {
            add
            {
                _onRefresh += value;
            }
            remove
            {
                _onRefresh -= value;
            }
        }

        #endregion

        /// <summary>
        /// Создать отрисовщик для элемента
        /// </summary>
        /// <param name="parent">Отрисовываемый элемент</param>
        public ElementImage(BaseElement parent)
        {
            _Parent = parent;
        }

        /// <summary>
        /// Получить изображение текущего элемента
        /// </summary>
        /// <returns>Изображение</returns>
        public Image DrawToImage()
        {
            Image result = null;
            if (_ResultImage == null)
            {
                if (_TemplateImage == null)
                    _TemplateImage = new Bitmap(_Width, _Height);
                result = (Image)_TemplateImage.Clone();

                if (_onPaint != null)
                    _onPaint(result, _Parent);
                _ResultImage = result;
            }
            else
                result = _ResultImage;
            return result;
        }

        /// <summary>
        /// Обновить шаблон изображения
        /// </summary>
        public void RefreshTemplate()
        {
            if (_TemplateImage != null)
            {
                if (_onRefresh != null)
                    _onRefresh(this.Parent);
                this._TemplateImage.Dispose();
                this._TemplateImage = null;
                this._ResultImage.Dispose();
                this._ResultImage = null;
                ImageFile = _ImgFile;
            }
        }

        /// <summary>
        /// Проверить элемент на попадание под выделение
        /// </summary>
        /// <param name="x">X координата клика</param>
        /// <param name="y">Y координата</param>
        /// <returns></returns>
        public virtual bool CheckSelection(int x, int y)
        {
            bool res = (x >= _Left) && (x <= _Left + _Width) && (y >= _Top) && (y <= _Top + _Height);
            return res;
        }

        /// <summary>
        /// Получить сведения о подключаемом PIN'е
        /// </summary>
        /// <param name="x">X координата на холсте</param>
        /// <param name="y">Y координата на холсте</param>
        /// <returns>PIN</returns>
        public virtual PIN GetBindingPIN(int x, int y)
        {
            PIN res = null;
            if ((_Parent != null) && (_Parent is CircuitElement))
            {
                CircuitElement ce = _Parent as CircuitElement;
                x = x - Left + 2;
                y = y - Top + 2;
                int i = 0;
                while ((i < ce.PINs.Count) && (ce.PINs[i].DrawOptions.CheckSelection(x,y) == false))
                    i++;
                if (i < ce.PINs.Count)
                    res = ce.PINs[i];
            }
            return res;
        }
    }
}